package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.zzyl.base.PageResponse;
import com.zzyl.constant.SuperConstant;
import com.zzyl.dto.RoleAddDto;
import com.zzyl.dto.RolePageDto;
import com.zzyl.dto.RoleUpdateDto;
import com.zzyl.entity.Role;
import com.zzyl.entity.RoleResource;
import com.zzyl.entity.User;
import com.zzyl.entity.UserRole;
import com.zzyl.enums.BasicEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.RoleMapper;
import com.zzyl.mapper.RoleResourceMapper;
import com.zzyl.mapper.UserRoleMapper;
import com.zzyl.service.RoleService;
import com.zzyl.vo.RoleVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class RoleServiceImpl implements RoleService {
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private RoleResourceMapper roleResourceMapper;
    @Autowired
    private UserRoleMapper userRoleMapper;


    @Override
    public PageResponse rolePage(Integer pageNum, Integer pageSize, RolePageDto dto) {
        PageHelper.startPage(pageNum, pageSize);
        Page<RoleVo> roleVoPage = roleMapper.rolePage(dto);
        return PageResponse.of(roleVoPage,RoleVo.class);
    }

    @Override
    public void addRole(RoleAddDto dto) {
        // 判断重复
        Role roleDB = roleMapper.selectByName(dto.getRoleName());
        if(roleDB != null){
            throw new BaseException(BasicEnum.DATA_EXIST);
        }
        Role role = BeanUtil.copyProperties(dto, Role.class);
        roleMapper.insert(role);
    }

    @Override
    public void deleteRole(String roleIds) {
        Role role = roleMapper.selectByPrimaryKey(Long.valueOf(roleIds));
        if(role == null){
            throw new BaseException(BasicEnum.DATA_NOT_EXIST);
        }
        // 判断状态，如果是启用 禁止删除
        if(Objects.equals(role.getDataState(), SuperConstant.DATA_STATE_0)){
            throw new BaseException(BasicEnum.CANNOT_DELETE_ROLE);
        }
        // 删除role
        roleMapper.deleteByPrimaryKey(Long.valueOf(roleIds));
        // 删除role_resource
        roleResourceMapper.deleteRoleCheckedResources(Long.valueOf(roleIds));
    }

    @Override
    public List<String> findRoleCheckedResources(Long roleId) {
        return roleResourceMapper.findRoleCheckedResources(roleId);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateRole(RoleUpdateDto dto) {
        // 判断名称是否重复
        Role roleDB = roleMapper.selectByName(dto.getRoleName());
        if(roleDB != null){
            // 名称重复后判断id是否相同
            if(!Objects.equals(roleDB.getId(), dto.getId())){
                throw new BaseException(BasicEnum.DATA_EXIST);
            }
        }

        //处理启用禁用
        //先查询角色的原始状态
        Role role1 = roleMapper.selectByPrimaryKey(dto.getId());
        if(role1 == null){
            throw new BaseException(BasicEnum.DATA_NOT_EXIST);
        }
        //更新状态
        if(!Objects.equals(role1.getDataState(), dto.getDataState())){
            // 如果是禁用，判断是否关联到了用户
            if(Objects.equals(dto.getDataState(), SuperConstant.DATA_STATE_1)){
                List<User> userList = userRoleMapper.selectUserByRoleId(dto.getId());
                if(!CollectionUtils.isEmpty(userList)){
                    throw new BaseException(BasicEnum.ROLE_STATUS);
                }
            }
        }
        Role role = BeanUtil.copyProperties(dto, Role.class);
        //更新角色
        roleMapper.updateByPrimaryKeySelective(role);
        //兼容处理，若只更改菜单名的话，前端是不传资源列表的，不加这个判断就会误删
        if(dto.getCheckedResourceNos()==null){
            return;
        }
        //先删除与角色关联的资源
        roleResourceMapper.deleteRoleCheckedResources(dto.getId());
        if(!CollectionUtils.isEmpty(dto.getCheckedResourceNos())){//若有新的关联资源
            //重新组装
            List<RoleResource> collect = dto.getCheckedResourceNos().stream().map(s -> {
                RoleResource roleResource = new RoleResource();
                roleResource.setRoleId(dto.getId());
                roleResource.setResourceNo(s);
                roleResource.setDataState(SuperConstant.DATA_STATE_0);
                return roleResource;
            }).collect(Collectors.toList());
            //再新增进去
            roleResourceMapper.batchInsert(collect);
        }

    }

    @Override
    public List<RoleVo> getAllRoles() {

        return roleMapper.getAllRoles();
    }
}
